#pragma once

struct OperatingActivityUserDataBase {
	virtual ~OperatingActivityUserDataBase() {}
};

class OperatingActivityBase
{
public:
	OperatingActivityBase(const OperatingActivity* pProto, ssize_t nSaveData);
	virtual ~OperatingActivityBase();

	virtual GErrorCode OnPlayerBuy(INetPacket& pck, const OperatingPlayerInfo& info, uint32 index) { return CommonNotImplemented; }
	virtual GErrorCode OnPlayerGetReward(INetPacket& pck, const OperatingPlayerInfo& info, uint32 index) { return CommonNotImplemented; }

	virtual bool OnPlayerLogin(const OperatingPlayerInfo& info) { return false; }
	virtual bool OnPlayerPay(const OperatingPlayerInfo& info, uint32 rmbVal, uint32 goldVal, uint32 payType) { return false; }
	virtual bool OnPlayerCost(const OperatingPlayerInfo& info, uint32 goldVal, uint32 costType) { return false; }
	virtual bool OnPlayerGainScore(const OperatingPlayerInfo& info, uint32 scoreValue, uint32 scoreType) { return false; }
	virtual bool OnPlayerPlayActvt(const OperatingPlayerInfo& info, OperatingPlayType playType, const uint32 params[]) { return false; }
	virtual bool OnPlayerEventActvt(const OperatingPlayerInfo& info, OperatingEventType eventType, const uint32 params[]) { return false; }

	virtual void OnDayEnd() {}
	virtual void OnActivityEnd() { m_isActEnd = true; }

	virtual bool IsHide(const OperatingPlayerInfo& info) const { return false; }
	virtual bool IsFinished(const OperatingPlayerInfo& info) const { return false; }
	virtual bool HasShortHot(const OperatingPlayerInfo& info) const { return false; }

	virtual void LoadActivityCares(std::bitset<(int)OperatingCareType::Count>& cares) {}

	void BuildActivityDetailPacket(NetPacket& pck, const OperatingPlayerInfo& info);
	void BuildActivityIntroPacket(NetPacket& pck, const OperatingPlayerInfo& info);

	void InitActivityInstance();
	void ResetActivityPrototype(const OperatingActivity* pProto);

	const OperatingActivity* GetProto() const { return m_pProto; }
	bool IsActivityEnd() const { return m_isActEnd; }

protected:
	void LoadDataFromDB();
	void SaveDataToDB(uint32 playerId);
	void SaveDataToDB(const std::vector<uint32>& playerIds);

	virtual void OnLoadDataFromDB() {}
	virtual void OnPreSaveDataToDB(OperatingActivityData& actData) {}

	virtual void ReloadActivityParams() {}
	virtual void BuildActivityParamsPacket(NetPacket& pck, const OperatingPlayerInfo& info) {}

	void BroadcastActivityDataDirty() const;

	OperatingActivityData* GetActivityData(uint32 playerId) const;
	OperatingActivityData* CreateAndGetActivityData(uint32 playerId);
	void InitActivityData(uint32 playerId, OperatingActivityData& actData) const;
	static void ClearActivitySaveData(OperatingActivityData& actData);

	OperatingActivityUserDataBase* GetActivityUserData(uint32 playerId) const;
	OperatingActivityUserDataBase* CreateAndGetActivityUserData(const OperatingActivityData& actData);
	virtual OperatingActivityUserDataBase* CreateActivityUserData(const OperatingActivityData& actData) { return NULL; }

	void SendRewardMail(uint32 playerId,
		const std::vector<FItemInfo>& rewardItems,
		uint32 subjectStrId, uint32 bodyStrId,
		const std::string_view& subjectArgs = emptyStringView,
		const std::string_view& bodyArgs = emptyStringView,
		size_t times = 1);

	GErrorCode GetRewardItems(const OperatingPlayerInfo& info,
		const std::vector<FItemInfo>& rewardItems,
		bool isAllowMail = false, size_t times = 1,
		const std::function<bool()>& errResp = nullptr);

	const OperatingActivity* m_pProto;
	const ssize_t m_nSaveData;
	bool m_isActEnd;

	std::unordered_map<uint32, OperatingActivityData*> m_mapActData;
	std::unordered_map<uint32, OperatingActivityUserDataBase*> m_mapActUserData;
};
